<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>5.1.1-理解 Proxy 和 Reflect</title>
</head>

<body>
    <div id="container"></div>
</body>
<script>
    /**
     * 什么是 Proxy 呢？
     * - 使用 Proxy 可以创建一个代理对象。
     * - 它能够实现对其他对象的代理，这里的关键词是其他对象，
     * - 也就是说，Proxy 只能代理对象，无法代理非对象值，例如字符串、布尔值等。
     * 
     * 代理指的是什么？
     * - 指的是对一个对象基本语义的代理。
     * - 它允许我们拦截并重新定义对一个对象的基本操作。
     *
     * 什么是基本语义？
     * - 给出一个对象 obj，可以对它进行一些操作
     * - 类似这种读取、设置属性值的操作，就属于基本语义的操作
     * - 一个函数也是一个对象，所以调用函数也是对一个对象的基本操作
     * 
     * 01 obj.foo // 读取属性 foo 的值
     * 02 obj.foo++ // 读取和设置属性 foo 的值
     * 
     * Proxy 只能够拦截对一个对象的基本操作
    */
    const fn = (name) => {
        console.log('我是：', name)
    }

    // 调用函数是对对象的基本操作
    fn()

    // 用 Proxy 来拦截函数的调用操作
    const p2 = new Proxy(fn, {
        // 使用 apply 拦截函数调用
        apply(target, thisArg, argArray) {
            target.call(thisArg, ...argArray)
        }
    })

    p2('hcy') // 输出：'我是：hcy'

    
    /**
     * 什么是非基本操作呢？
     * - 其实调用对象下的方法就是典型的非基本操作，我们叫它复合操作
     * 
     * 01 obj.fn()
     * 
     * 调用一个对象下的方法，是由两个基本语义组成的
     * - 第一个基本语义是 get，即先通过 get 操作得到 obj.fn 属性
     * - 第二个基本语义是函数调用，即通过 get 得到 obj.fn 的值后再调用它，
     *    也就是我们上面说到的 apply
     * 
    */

</script>

</html>